package com.sasken.pdb.views.renderers
{
	import com.sasken.pdb.controllers.events.FilterEvent;
	import com.sasken.pdb.controllers.events.ItemRendererEvent;
	import com.sasken.pdb.controllers.interfaces.IDataProviderRenderer;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import mx.collections.ArrayCollection;
	import mx.containers.VBox;
	import mx.controls.ComboBox;
	import mx.controls.Label;
	import mx.controls.TextInput;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridHeaderRenderer;
	import mx.core.FlexTextField;
	import mx.core.ScrollPolicy;
	import mx.events.FlexEvent;

	/**
	 *  Data grid header renderer that adds filter fields to the header and dispatches FilterEvents accordingly.  
	 */ 
	public class DataGridFilterHeaderRenderer extends AdvancedDataGridHeaderRenderer implements IDataProviderRenderer
	{
		private var _labelTitle:Label;
		
		private var vBox:VBox;
		
		private var _filterFieldCombo:ComboBox;
		private var _filterFieldText:TextInput;
		private var usingComboBox:Boolean;
		
		private var _dataProvider:ArrayCollection = new ArrayCollection();
		private var _sortable:Boolean;
		
		public function DataGridFilterHeaderRenderer()
		{
			super();
			
			_labelTitle = new Label();
			_labelTitle.text = "Loading...";
			_labelTitle.truncateToFit = false;
			_labelTitle.percentWidth = 100;
			_labelTitle.setStyle("fontWeight", "bold");
			_labelTitle.setStyle("textAlign", "center");
			

			
			_filterFieldCombo = new ComboBox();
			_filterFieldCombo.editable = true;
			usingComboBox = true;

			_filterFieldText = new TextInput();
			_filterFieldText.percentWidth = 100;
			
			vBox = new VBox();
			vBox.horizontalScrollPolicy = ScrollPolicy.OFF;
			vBox.styleName = this.styleName ;
			vBox.setStyle("horizontalAlign","center");
			vBox.percentWidth = 100;
			vBox.percentHeight = 100;
			vBox.setStyle("paddingLeft", 2);
			vBox.addChild(_labelTitle);

			addChild(vBox);
			//addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
			
			addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteListener);
			
			_filterFieldText.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
			_filterFieldText.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);	
			_filterFieldText.addEventListener(Event.CHANGE, filterChangeListener);
			_filterFieldText.addEventListener(KeyboardEvent.KEY_UP, enterPressListener);
			
			_filterFieldCombo.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
			_filterFieldCombo.addEventListener(FocusEvent.FOCUS_OUT, onFocusOut);	
			_filterFieldCombo.addEventListener(Event.CHANGE, filterChangeListener);
			_filterFieldCombo.addEventListener(KeyboardEvent.KEY_UP, enterPressListener);
		}
		
		private function enterPressListener(e:KeyboardEvent):void
		{
			if (e.keyCode == Keyboard.ENTER)
			{
				var inputText:String = _filterFieldCombo.text;
				
				if (!usingComboBox)
				{
					inputText = _filterFieldText.text;
				}
			
				dispatchEvent(new FilterEvent(FilterEvent.FILTER_EVENT, 
						  inputText, AdvancedDataGridColumn(data), 
										  true, true));
										  
				dispatchEvent(new FilterEvent(FilterEvent.FILTER_REFRESH_EVENT, 
						  	  "enter", AdvancedDataGridColumn(data), true, true));
			}
			
		}
		
				
		/**
		 * When the filter Text input gets focus we need to make Column unsortable.
		 * Othrwise, Focus will move out of the text input ( Because of sorting ). 
		 * because of this, we can not type the text properly
		 */
		private function onFocusIn(event:FocusEvent):void 
		{						
			if (data)
			{
				//Alert.show(".." + data, "...");
				_sortable = (data as AdvancedDataGridColumn).sortable;
				(data as AdvancedDataGridColumn).sortable = false;
			}
			
			if (usingComboBox)
			{
				
			}
			else
			{
				_filterFieldText.focusManager.activate();
				_filterFieldText.focusEnabled = true;
				_filterFieldText.focusManager.setFocus(_filterFieldText);
				_filterFieldText.setFocus();		
			}
			
			//trace("focus in to " + this + AdvancedDataGridColumn(data).headerText);
		}
		
		/**
		 * When the filter Text input loses its focus, 
		 * We need to restore the 'sortable' value to the Column
		 */
		private function onFocusOut(event:FocusEvent):void 
		{
			if (data)
			{
				//Alert.show(".." + data, "...");
				//(data as AdvancedDataGridColumn).sortable = _sortable ;			
			}
			//trace(event.relatedObject);
			//trace("focus lost from " + this+ AdvancedDataGridColumn(data).headerText);
		}
		
		private function filterChangeListener(e:Event):void
		{
			// TODO timer
		
		}	
		
		private function creationCompleteListener(e:FlexEvent):void
		{
			removeChild(label as DisplayObject);
			//_labelTitle.text = (label as FlexTextField).text;
			
			dispatchEvent(new ItemRendererEvent(ItemRendererEvent.EVENT_PASS_DATAPROVIDER, 
												AdvancedDataGridColumn(data), this, 
												true, true));
		}
		
		/**
		 * Default behavior is overridden to add a hook the display list update sequence.
		 * In the hook, a private renderer must be called that makes sure all items are
		 * properly displayed.
		 * <p></p>
		*/
		override protected function measure():void 
		{		
			super.measure();			
			rendererHook();
		}
		
		/**
		 * Default behavior is overridden to add a hook the display list update sequence.
		 * In the hook, a private renderer must be called that makes sure all items are
		 * properly displayed. 
		 * @param unscaledWidth Specifies the width of the component, in pixels, in the component's coordinates, regardless of the value of the scaleX property of the component.
		 * @param unscaledHeight  Specifies the height of the component, in pixels, in the component's coordinates, regardless of the value of the scaleY property of the component.
		 * <p></p>
		*/
		override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void 
		{		
			super.updateDisplayList(unscaledWidth,unscaledHeight);				
			rendererHook();		
		}
		
		private function rendererHook():void		
		{
			var rightMargin:int = 20;
			
			vBox.setActualSize( getExplicitOrMeasuredWidth() - rightMargin, vBox.getExplicitOrMeasuredHeight()) ;
			//_labelTitle.setActualSize(getExplicitOrMeasuredWidth() - rightMargin, _labelTitle.getExplicitOrMeasuredHeight()) ;
			
			measuredHeight = measuredMinHeight = vBox.getExplicitOrMeasuredHeight() ;
			measuredWidth = measuredMinWidth = vBox.getExplicitOrMeasuredWidth();
			
			if (usingComboBox)
			{
				_filterFieldCombo.width = vBox.width - 2; // -2 for margin on left side
			}
		}
		
		public function set title(value:String):void
		{
			_labelTitle.text = value;
		}
		
		public function set dataProvider(_dp:Object):void
		{
			if (_dp is ArrayCollection)
			{
				_dataProvider = ArrayCollection(_dp);
				_filterFieldCombo.dataProvider = _dataProvider;
				vBox.addChild(_filterFieldCombo);
			}
			else
			{
				vBox.addChild(_filterFieldText);
				usingComboBox = false;
			}	
		}
		
		
	}
}